package
{
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.utils.Dictionary;
import flash.display.Graphics;
import flash.geom.Rectangle;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;

public class MoveTool extends Tool
{
	protected var target:Object;
	protected var addPoint:Object;
	protected var targetLine:Object;
	
	protected var controlPoint:Object;
	protected var controlLine:Object;
	protected var isDown:Boolean;
	protected var isDragUp:Boolean;
	
	//caught down only for down process,to let mouse_mc get down action and cancel default
	protected var caughtDown:Boolean;
	
	public function MoveTool()
	{
		super();
		this.keyCode=82;
	}
	
	override public function down():void{
		isDragUp=false;
		if(caughtDown)return;
		
		var p:Object=canvas.getClosePoint();
		if(p){
			target=p;
		}else{
			//here is down on space
			var line:Array=canvas.getCloseLine();
			if(select_rect==null && line.length==0){
				var mp:Object=canvas.mousePoint(false);
				select_rect=new Rectangle(mp.x,mp.y,0,0);
			}
		}
	
		isDown=true;
		downPoint=canvas.mousePoint(false);
	}
	
	override public function keyDownHandler(evt:KeyboardEvent):void{
		//left 37
		//up 38
		//right 39
		//down 40
		if(canvas.selection.getLength()>0){
			var itr:Iterator=new Iterator(canvas.selection.toArray());
			var item:Object;
			var step:Number=1;
			
		//steps to move the point
		if(evt.keyCode==37){
			
			while(itr.hasNext()){
				item=itr.next() as Object;
				item.x-=step;
			}
			canvas.render();
			
		}else if(evt.keyCode==38){
			
			while(itr.hasNext()){
				item=itr.next() as Object;
				item.y-=step;
			}
			canvas.render();
		}else if(evt.keyCode==39){
		
			while(itr.hasNext()){
				item=itr.next() as Object;
				item.x+=step;
			}
			canvas.render();
		}else if(evt.keyCode==40){
		
			while(itr.hasNext()){
				item=itr.next() as Object;
				item.y+=step;
			}
			canvas.render();
		}
		}
	}
	
	private var downPoint:Object;
	protected var select_rect:Rectangle;
	private var draging:Boolean;
	
	override public function move():void{
		isDragUp=true;
		
		if(isDown && select_rect==null && canvas.selection.getLength()>0){
			var mp2:Object=canvas.mousePoint(false);
			if(!draging){
				var itr:Iterator=new Iterator(canvas.selection.toArray());
				var item:Object;
				while(itr.hasNext()){
					item=itr.next() as Object;
					item.x-=downPoint.x-mp2.x;
					item.y-=downPoint.y-mp2.y;
				}
				downPoint=mp2;
				return;
			}
		}
		
		//if is selecting virtual rect
		if(select_rect!=null){
			var mp:Object=canvas.mousePoint(false);
			var w:Number=mp.x-select_rect.x;
			var h:Number=mp.y-select_rect.y;
			
			select_rect.width=w;
			select_rect.height=h;
			resetSelection();
			return;
		}
		
		//if not then...
		var line:Array=canvas.getCloseLine();
		if(target){
			var p:Object=canvas.mousePoint();
			
			if(!target.isRect){
				target.x=p.x;
				target.y=p.y;
			}else{
				//here drag rect
				//get 3 points of the target
				var datas:Array=canvas.getCorner(target);

				var center:Object=canvas.data[datas[0]];
				var p1:Object=canvas.data[datas[1]];
				var p2:Object=canvas.data[datas[2]];
				
				//then calculate portion of the mouse point
				
				var mp_path:Object=getPointOnClosePath();
				if(mp_path==null)return;
				var portion:Number=canvas.getPortionNumber(p1,p2,mp_path);
				
				//then change the portion to the object point
				var r:Rect=canvas.getRect2(target);
				
				r.portion=portion;
				
			}
		}else if(isDown && line.length==1){
			//drag on line
			if(controlPoint==null){
				controlPoint=addPoint;
				controlPoint.id=canvas.getNewId();
				controlPoint.isControl=true;
				canvas.addPoint(controlPoint);
				
				target=controlPoint;
				controlLine=targetLine;
				controlLine.control=controlPoint.id;
			}
			
		}
	}
	
	override public function up():void{
		caughtDown=false;
		if(select_rect){
			//create hole
			trace("select_rect:");
			if(select_rect.width==0 && select_rect.height==0){
				upOnSpaceWithNoDrag();
			}
			//and clear the select rect
			resetSelection();
			select_rect=null;
		}else if(target){
			//no drag just up
			if(isDragUp==false)
			directUpHandler(target);
			
			//finish up handler
			target=null;
			controlPoint=null;
			
		}else if(addPoint){
			upAddPointAction();
		}
		isDown=false;
	}
	
	public function upOnSpaceWithNoDrag():void{
		
	}
	
	public function directUpHandler(target:Object):void{
	
	}
	
	public function upAddPointAction():void{
		addPoint.id=canvas.getNewId();
		targetLine.splitPath(addPoint);
	}
	
	public function resetSelection():void{
			//take selections here from select_rect
			var rect:Rectangle=select_rect.clone();
			
			if(rect.top>rect.bottom){
				var top:Number=rect.top;
				rect.top=rect.bottom;
				rect.bottom=top;
			}
			if(rect.left>rect.right){
				var left:Number=rect.left;
				rect.left=rect.right;
				rect.right=left;
			}
			canvas.setSelection(rect);
	}
	
	public function getPointOnClosePath():Object{
		var ps:Array=canvas.getCloseLine();
		if(ps.length==0)return null;
		var pp:Object=canvas.getCloestPointOnPath(canvas.simpleMousePoint(),Path(ps[0]));
		
		return pp;
		
	}
	
	override public function renderMouseMC(mouse_mc:Sprite):void{
		var p:Item=canvas.getClosePoint();
		canvas.removeChildren(mouse_mc);
		if(p){
			mouse_mc.addChild(getHandler(p));
		}
		
		var ps:Array=canvas.getCloseLine();
		
			if(ps.length==1){
				var pp:Object=canvas.getCloestPointOnPath(canvas.simpleMousePoint(),Path(ps[0]));
				if(pp!=null){
					mouse_mc.addChild(getHandler(pp));
					addPoint=new PointObj();
					addPoint.x=pp.x;
					addPoint.y=pp.y;
					targetLine=ps[0];
				}
			}else{
				addPoint=null;
			}
		
		//draw controler line
		var itr:Iterator=new Iterator(canvas.paths.toArray());
		var path:Path;
		var path_pen:Graphics=canvas.path_pen;
		var data:Array=canvas.data;
		while(itr.hasNext()){
			
			path=itr.next() as Path;
			var from:Object=data[path.from];
			var to:Object=data[path.to];
			
			if(path.control!=-1){
				var control:Object=data[path.control];
				
				//draw controler line
				path_pen.lineStyle(1,0x0099ff,0.5);
				path_pen.moveTo(from.x,from.y);
				path_pen.lineTo(control.x,control.y);
				path_pen.lineTo(to.x,to.y);
			}else{
				//here is normal straight line, draw center point to draw as curve
				
			}
		}
		
		if(select_rect){
			trace("draw select rect");
			//draw the select rect
			var s:Sprite=new Sprite();
			var g:Graphics=s.graphics;
			g.lineStyle(1,0x0066cc,1);
			g.beginFill(0x0066cc,0.1);
			g.drawRect(select_rect.x,select_rect.y,select_rect.width,select_rect.height);
			g.endFill();
			mouse_mc.addChild(s);
		}
		
	}
	
	public function getCenter(from:Object,to:Object):Object{
		var x:Number=(from.x+to.x)/2;
		var y:Number=(from.y+to.y)/2;
		
		return {x:x,y:y};
	}
	
	public function drawSelectedPoint(point:Object,point_pen:Graphics,mouse_mc:Sprite):void{
		//is selected
		point_pen.beginFill(0x3399ff,1);
		point_pen.drawRect(point.x-3,point.y-3,6,6);
		point_pen.endFill();
		
	}
	
	public function drawPoint(point:Object,point_pen:Graphics):void{
		point_pen.drawRect(point.x-3,point.y-3,6,6);
	}
	
	override public function drawPoints(points:Collection,point_pen:Graphics):void{
		//draw points 
		var itr:Iterator=new Iterator(points.toArray());
		var point:Object;
		point_pen.clear();
		point_pen.lineStyle(1,0x000000,1);
		while(itr.hasNext()){
			point=itr.next();
			
			if(canvas.selection.contains(point)){
				drawSelectedPoint(point,point_pen,canvas.mouse_mc);
			}else{
				//if(point.isColor)continue;
				drawPoint(point,point_pen);
			}
		}
	}
}

}

